home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.3 (Developer)…68k, x86, SPARC, PA-RISC] / NeXTSTEP 3.3 Dev Intel.iso / NextDeveloper / Source / GNU / cctools / as / layout.c < prev    next >
C/C++ Source or Header  |  1994-06-03  |  20KB  |  684 lines

  1. /* layout.c (was part of write.c in original GAS version)
  2.    Copyright (C) 1986,1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "stuff/round.h"
  23. #include "as.h"
  24. #include "sections.h"
  25. #include "frags.h"
  26. #include "symbols.h"
  27. #include "fixes.h"
  28. #include "messages.h"
  29. #include "expr.h"
  30. #include "md.h"
  31. #include "obstack.h"
  32.  
  33. static void fixup_section(
  34.     fixS *fixP,
  35.     int nsect);
  36. static void relax_section(
  37.     struct frag *section_frag_root,
  38.     int nsect);
  39. static relax_addressT relax_align(
  40.     relax_addressT address,
  41.     long alignment);
  42. static int is_down_range(
  43.     struct frag *f1,
  44.     struct frag *f2);
  45.  
  46. /*
  47.  * layout_addresses() is called after all the assembly code has been read and
  48.  * fragments, symbols and fixups have been created.  This routine sets the
  49.  * address of the fragments and symbols.  Then it does the fixups of the frags
  50.  * and prepares the fixes so relocation entries can be created from them.
  51.  */
  52. void
  53. layout_addresses(
  54. void)
  55. {
  56.     struct frchain *frchainP;
  57.     fragS *fragP;
  58.     relax_addressT slide, tmp;
  59.     symbolS *symbolP;
  60.  
  61.     if(frchain_root == NULL)
  62.         return;
  63.  
  64.     /*
  65.      * If there is any current frag close it off.
  66.      */
  67.     if(frag_now != NULL && frag_now->fr_fix == 0){
  68.         frag_now->fr_fix = obstack_next_free(&frags) -
  69.                    frag_now->fr_literal;
  70.         frag_wane(frag_now);
  71.     }
  72.  
  73.     /*
  74.      * For every section, add a last ".fill 0" frag that will later be used
  75.      * as the ending address of that section.
  76.      */
  77.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  78.         /*
  79.          * We must do the obstack_finish(), so the next object we put on
  80.          * obstack frags will not appear to start at the fr_literal of the
  81.          * current frag.  Also, it ensures that the next object will begin
  82.          * on a address that is aligned correctly for the engine that runs
  83.          * the assembler.
  84.          */
  85.         obstack_finish(&frags);
  86.  
  87.         /*
  88.          * Make a fresh frag for the last frag.
  89.          */
  90.         frag_now = (fragS *)obstack_alloc(&frags, SIZEOF_STRUCT_FRAG);
  91.         memset(frag_now, '\0', SIZEOF_STRUCT_FRAG);
  92.         frag_now->fr_next = NULL;
  93.         obstack_finish(&frags);
  94.  
  95.         /*
  96.          * Append the new frag to current frchain.
  97.          */
  98.         frchainP->frch_last->fr_next = frag_now;
  99.         frchainP->frch_last = frag_now;
  100.         frag_wane(frag_now);
  101.  
  102.     }
  103.  
  104.     /*
  105.      * Now set the relitive addresses of frags within the section by
  106.      * relaxing each section.  That is all sections will start at address
  107.      * zero and addresses of the frags in that section will increase from
  108.      * there.
  109.      */
  110.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  111.         if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL)
  112.         continue;
  113.         /*
  114.          * This is done so in case md_estimate_size_before_relax() (called
  115.          * by relax_section) wants to make fixSs they are for this
  116.          * section.
  117.          */
  118.         frchain_now = frchainP;
  119.  
  120.         relax_section(frchainP->frch_root, frchainP->frch_nsect);
  121.     }
  122.  
  123.     /*
  124.      * Now set the absolute addresses of all frags by sliding the frags in
  125.      * each non-zerofill section by the address ranges taken up by the
  126.      * sections before it.
  127.      */ 
  128.     slide = 0;
  129.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  130.         if((frchainP->frch_section.flags & SECTION_TYPE) == S_ZEROFILL)
  131.         continue;
  132.         slide = round(slide, 1 << frchainP->frch_section.align);
  133.         tmp = frchainP->frch_last->fr_address;
  134.         if(slide != 0){
  135.         for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){
  136.             fragP->fr_address += slide;
  137.         }
  138.         }
  139.         slide += tmp;
  140.     }
  141.     /*
  142.      * Now with the non-zerofill section addresses set set all of the
  143.      * addresses of the zerofill sections.  Comming in the fr_address is
  144.      * the size of the section and going out it is the start address.  This
  145.      * will make layout_symbols() work out naturally.  The only funky thing
  146.      * is that section numbers do not end up in address order.
  147.      */
  148.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  149.         if((frchainP->frch_section.flags & SECTION_TYPE) != S_ZEROFILL)
  150.         continue;
  151.         slide = round(slide, 1 << frchainP->frch_section.align);
  152.  
  153.         tmp = frchainP->frch_root->fr_address;
  154.         frchainP->frch_root->fr_address = slide;
  155.         frchainP->frch_last->fr_address = tmp + slide;
  156.         slide += tmp;
  157.     }
  158.  
  159.     /*
  160.      * Set the symbol addresses based on there frag's address.
  161.      * First forward references are handled.
  162.      */
  163.     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
  164.         if(symbolP->sy_forward != NULL){
  165.         if(symbolP->sy_nlist.n_type & N_STAB)
  166.             symbolP->sy_other = symbolP->sy_forward->sy_other;
  167.         symbolP->sy_value += symbolP->sy_forward->sy_value +
  168.                      symbolP->sy_forward->sy_frag->fr_address;
  169.         symbolP->sy_forward = 0;
  170.         }
  171.     }
  172.     for(symbolP = symbol_rootP; symbolP; symbolP = symbolP->sy_next){
  173.         symbolP->sy_value += symbolP->sy_frag->fr_address;
  174.     }
  175.  
  176.     /*
  177.      * At this point the addresses of frags now reflect addresses we use in 
  178.      * the object file and the symbol values are correct.
  179.      * Scan the frags, converting any ".org"s and ".align"s to ".fill"s.
  180.      * Also converting any machine-dependent frags using md_convert_frag();
  181.      */
  182.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  183.         /*
  184.          * This is done so any fixes created by md_convert_frag() are for
  185.          * this section.
  186.          */
  187.         frchain_now = frchainP;
  188.  
  189.         for(fragP = frchainP->frch_root; fragP; fragP = fragP->fr_next){
  190.         switch(fragP->fr_type){
  191.         case rs_align:
  192.         case rs_org:
  193.             fragP->fr_type = rs_fill;
  194.             know(fragP->fr_var == 1);
  195.             know(fragP->fr_next != NULL);
  196.             fragP->fr_offset = fragP->fr_next->fr_address -
  197.                        fragP->fr_address -
  198.                        fragP->fr_fix;
  199.             break;
  200.  
  201.         case rs_fill:
  202.             break;
  203.  
  204.         case rs_machine_dependent:
  205.             md_convert_frag(fragP);
  206.             /*
  207.              * After md_convert_frag, we make the frag into a ".fill 0"
  208.              * md_convert_frag() should set up any fixSs and constants
  209.              * required.
  210.              */
  211.             frag_wane(fragP);
  212.             break;
  213.  
  214.         default:
  215.             BAD_CASE(fragP->fr_type);
  216.             break;
  217.         }
  218.         }
  219.     }
  220.  
  221.     /*
  222.      * For each section do the fixups for the frags.
  223.      */
  224.     for(frchainP = frchain_root; frchainP; frchainP = frchainP->frch_next){
  225.         fixup_section(frchainP->frch_fix_root, frchainP->frch_nsect);
  226.     }
  227. }
  228.  
  229. /*
  230.  * fixup_section() does the fixups of the frags and prepares the fixes so
  231.  * relocation entries can be created from them.  The fixups cause the contents
  232.  * of the frag to have the value for the fixup expression.  A fix structure that
  233.  * ends up with a non NULL fx_addsy will have a relocation entry created for it.
  234.  */
  235. static
  236. void
  237. fixup_section(
  238. fixS *fixP,
  239. int nsect)
  240. {
  241.     symbolS *add_symbolP;
  242.     symbolS *sub_symbolP;
  243.     long value;
  244.     int size;
  245.     char *place;
  246.     long where;
  247.     char pcrel;
  248.     fragS *fragP;
  249.     int    add_symbol_N_TYPE;
  250.     int    add_symbol_nsect;
  251.  
  252.     /*
  253.      * The general fix expression is "fx_addsy - fx_subsy + fx_offset".
  254.      * The goal is to put the result of this expression into the frag at
  255.      * "place" for size "size".  The value of the expression is calculated
  256.      * in the variable "value" and starts with just the fx_offset.
  257.      */
  258.     for( ; fixP != NULL; fixP = fixP->fx_next){
  259.         fragP       = fixP->fx_frag;
  260.         know(fragP);
  261.         where    = fixP->fx_where;
  262.         place       = fragP->fr_literal + where;
  263.         size    = fixP->fx_size;
  264.         add_symbolP = fixP->fx_addsy;
  265.         sub_symbolP = fixP->fx_subsy;
  266.         value      = fixP->fx_offset;
  267.         pcrel       = fixP->fx_pcrel;
  268.  
  269.         add_symbol_N_TYPE = 0;
  270.         add_symbol_nsect = 0;
  271.  
  272.         if(add_symbolP != NULL){
  273.         add_symbol_N_TYPE = add_symbolP->sy_type & N_TYPE;
  274.         if(add_symbol_N_TYPE == N_SECT)
  275.             add_symbol_nsect = add_symbolP->sy_other;
  276.         }
  277.  
  278.         /*
  279.          * Is there a subtract symbol?
  280.          */
  281.         if(sub_symbolP){
  282.         /* is it just -sym ? */
  283.         if(add_symbolP == NULL){
  284.             if(sub_symbolP->sy_type != N_ABS)
  285.             as_warn("Negative of non-absolute symbol %s",
  286.                 sub_symbolP->sy_name);
  287.             value -= sub_symbolP->sy_value;
  288.             fixP->fx_subsy = NULL;
  289.         }
  290.         /*
  291.          * There are both an add symbol and a subtract symbol at this
  292.          * point.
  293.          *
  294.          * If both symbols are absolute then just calculate the
  295.          * value of the fix expression and no relocation entry will be
  296.          * needed.
  297.          */
  298.         else if((sub_symbolP->sy_type & N_TYPE) == N_ABS &&
  299.                 (add_symbolP->sy_type & N_TYPE) == N_ABS){
  300.             value += add_symbolP->sy_value - sub_symbolP->sy_value;
  301.             add_symbolP = NULL;
  302.             fixP->fx_addsy = NULL; /* no relocation entry */
  303.             fixP->fx_subsy = NULL;
  304.         }
  305.         /*
  306.          * If both symbols are defined in a section then calculate the
  307.          * value of the fix expression and let a section difference
  308.          * relocation entry be created.
  309.          */
  310.         else if((sub_symbolP->sy_type & N_TYPE) == N_SECT &&
  311.                 (add_symbolP->sy_type & N_TYPE) == N_SECT){
  312.             /*
  313.              * If we are allowed to use the new features that are
  314.              * incompatible with 3.2 then just calculate the value and
  315.              * let this create a SECTDIFF relocation type.
  316.              */
  317.             if(flagseen['k']){
  318.             value += add_symbolP->sy_value - sub_symbolP->sy_value;
  319.             goto down;
  320.             }
  321.             else{
  322.             /*
  323.              * This logic works only if the two symbols can't later
  324.              * be separated by scattered loading.  To make sure that
  325.              * this can't happen we would have to make sure all
  326.              * symbols associated with addresses between these two
  327.              * symbols including the add symbol are of the Lx form
  328.              * and the -L flag is not see so they will not appear
  329.              * in the output (if they are not in the output then the
  330.              * link editor can't separate the chain of frags by
  331.              * scattered loading).  Since this code does not make
  332.              * sure of this it is broken.  But this is a known bug
  333.              * in the NeXT 3.2 and earilier releases so this code is
  334.              * if'ed !flagseen['k'] and will make it compatable with
  335.              * 3.2 and previous releases.
  336.              */
  337.             if(sub_symbolP->sy_other == add_symbolP->sy_other){
  338.                 value += add_symbolP->sy_value -
  339.                      sub_symbolP->sy_value;
  340.                 add_symbolP = NULL;
  341.                 fixP->fx_addsy = NULL; /* no relocation entry */
  342.                 fixP->fx_subsy = NULL;
  343.             }
  344.             else{
  345.                 as_warn("Can't emit reloc {- symbol \"%s\"} @ file "
  346.                     "address %ld.", sub_symbolP->sy_name,
  347.                     fragP->fr_address + where);
  348.             }
  349.             }
  350.         }
  351.         /*
  352.          * If the subtract symbol is absolute subtract it's value from
  353.          * the fix expression and let a relocation entry get created
  354.          * that is not a section difference type.
  355.          */
  356.         else if(sub_symbolP->sy_type == N_ABS){
  357.             value -= sub_symbolP->sy_value;
  358.             fixP->fx_subsy = NULL; /* no SECTDIFF relocation entry */
  359.         }
  360.         /*
  361.          * At this point we have something we can't generate a
  362.          * relocation entry for (two undefined symbols, etc.).
  363.          */
  364.             else{
  365.              as_warn("Can't emit reloc {- symbol \"%s\"} @ file "
  366.                  "address %ld.", sub_symbolP->sy_name,
  367.                  fragP->fr_address + where);
  368.         }
  369.         }
  370.  
  371.         /*
  372.          * If a there is an add symbol in the fixup expression then add
  373.          * the symbol value into the fixup expression's value.
  374.          */
  375.         if(add_symbolP){
  376.         /*
  377.          * If this symbol is in this section and is pc-relative and we
  378.          * do not want to force a pc-relative relocation entry (to
  379.          * support scattered loading) then just calculate the value.
  380.          */
  381.         if(add_symbol_nsect == nsect &&
  382.            pcrel && !(fixP->fx_pcrel_reloc)){
  383.             /*
  384.              * This fixup was made when the symbol's section was
  385.              * unknown, but it is now in this section. So we know how
  386.              * to do the address without relocation.
  387.              */
  388.             value += add_symbolP->sy_value;
  389.             value -= size + where + fragP->fr_address;
  390.             pcrel = 0;    /* Lie. Don't want further pcrel processing. */
  391.             fixP->fx_addsy = NULL; /* No relocations please. */
  392.             /*
  393.              * It would be nice to check that the address does not
  394.              * overflow.
  395.              * I didn't do this check because:
  396.              * +  It is machine dependent in the general case (eg 32032)
  397.              * +  Compiler output will never need this checking, so why
  398.              *    slow down the usual case?
  399.              */
  400.         }
  401.         else{
  402.             switch(add_symbol_N_TYPE){
  403.             case N_ABS:
  404.             value += add_symbolP->sy_value;
  405.             fixP->fx_addsy = NULL; /* no relocation entry */
  406.             add_symbolP = NULL;
  407.             break;
  408.             
  409.             case N_SECT:
  410.             value += add_symbolP->sy_value;
  411.             break;
  412.             
  413.             case N_UNDF:
  414.             break;
  415.             
  416.             default:
  417.             BAD_CASE(add_symbol_N_TYPE);
  418.             break;
  419.             }
  420.         }
  421.         }
  422. down:
  423.         /*
  424.          * If the fixup expression is pc-relative then the value of the pc
  425.          * will be added to the expression when the machine executes the
  426.          * the instruction so we adjust the fixup expression's value by
  427.          * subtracting off the pc value (where) and adjust for insn size.
  428.          */
  429.         if(pcrel){
  430.         value -= size + where + fragP->fr_address;
  431.         if(add_symbolP == NULL){
  432.             fixP->fx_addsy = &abs_symbol; /* force relocation entry */
  433.         }
  434.         }
  435.  
  436.         if((size == 1 && (value & 0xffffff00) &&
  437.                 ((value & 0xffffff80) != 0xffffff80)) ||
  438.            (size == 2 && (value & 0xffff8000) &&
  439.                 ((value & 0xffff8000) != 0xffff8000)))
  440.         as_warn("Fixup of %ld too large for field width of %d",
  441.             value, size);
  442.  
  443.         /*
  444.          * Now place the fix expression's value in the place for the size.
  445.          * And save the fix expression's value to be used when creating
  446.          * a relocation entry if required.
  447.          */
  448.         md_number_to_imm(place, value, size, fixP, nsect);
  449.         fixP->fx_value = value;
  450.     }
  451. }
  452.  
  453.  
  454. /*
  455.  * relax_section() here we set the fr_address values in the frags.
  456.  * After this, all frags in this segment have addresses that are correct
  457.  * relative to the section (that is the section starts at address zero).
  458.  * After all of the sections have been processed by this call and their sizes
  459.  * are know then they can be slid to their final address.
  460.  */
  461. static
  462. void
  463. relax_section(
  464. struct frag *frag_root,
  465. int nsect)
  466. {
  467.     struct frag *fragP;
  468.     relax_addressT address;
  469.  
  470.     long stretch; /* May be any size, 0 or negative. */
  471.           /* Cumulative number of addresses we have */
  472.           /* relaxed this pass. */
  473.           /* We may have relaxed more than one address. */
  474.     long stretched;  /* Have we stretched on this pass? */
  475.             /* This is 'cuz stretch may be zero, when,
  476.                in fact some piece of code grew, and
  477.                another shrank.  If a branch instruction
  478.                doesn't fit anymore, we need another pass */
  479.  
  480.     const relax_typeS *this_type;
  481.     const relax_typeS *start_type;
  482.     relax_substateT next_state;
  483.     relax_substateT this_state;
  484.  
  485.     long growth;
  486.     long was_address;
  487.     long offset;
  488.     symbolS *symbolP;
  489.     long target;
  490.     long after;
  491.     long aim;
  492.  
  493.     growth = 0;
  494.  
  495.     /*
  496.      * For each frag in segment count and store (a 1st guess of) fr_address.
  497.      */
  498.     address = 0;
  499.     for(fragP = frag_root; fragP != NULL; fragP = fragP->fr_next){
  500.         fragP->fr_address = address;
  501.         address += fragP->fr_fix;
  502.         switch(fragP->fr_type){
  503.         case rs_fill:
  504.         address += fragP->fr_offset * fragP->fr_var;
  505.         break;
  506.  
  507.         case rs_align:
  508.         address += relax_align(address, fragP->fr_offset);
  509.         break;
  510.  
  511.         case rs_org:
  512.         /*
  513.          * Assume .org is nugatory. It will grow with 1st relax.
  514.          */
  515.         break;
  516.  
  517.         case rs_machine_dependent:
  518.         address += md_estimate_size_before_relax(fragP, nsect);
  519.         break;
  520.  
  521.         default:
  522.         BAD_CASE(fragP->fr_type);
  523.         break;
  524.         }
  525.     }
  526.  
  527.     /*
  528.      * Do relax().
  529.      * Make repeated passes over the chain of frags allowing each frag to
  530.      * grow if needed.  On each pass each frag's address is incremented by
  531.      * the accumulated growth, kept in stretched.  Passes are continued 
  532.      * until there is no stretch on the previous pass.
  533.      */
  534.     do{
  535.         stretch = 0;
  536.         stretched = 0;
  537.         for(fragP = frag_root; fragP != NULL; fragP = fragP->fr_next){
  538.         was_address = fragP->fr_address;
  539.         fragP->fr_address += stretch;
  540.         address = fragP->fr_address;
  541.         symbolP = fragP->fr_symbol;
  542.         offset = fragP->fr_offset;
  543.         switch(fragP->fr_type){
  544.         case rs_fill:    /* .fill never relaxes. */
  545.             growth = 0;
  546.             break;
  547.  
  548.         case rs_align:
  549.             growth = relax_align((relax_addressT)
  550.                      (address + fragP->fr_fix), offset) -
  551.                  relax_align((relax_addressT)
  552.                      (was_address + fragP->fr_fix), offset);
  553.             break;
  554.  
  555.         case rs_org:
  556.             target = offset;
  557.             if(symbolP != NULL){
  558.             know(((symbolP->sy_type & N_TYPE) == N_ABS) ||
  559.                  ((symbolP->sy_type & N_TYPE) == N_SECT));
  560.             know(symbolP->sy_frag);
  561.             know((symbolP->sy_type & N_TYPE) != N_ABS ||
  562.                  symbolP->sy_frag == &zero_address_frag );
  563.             target += symbolP->sy_value +
  564.                   symbolP->sy_frag->fr_address;
  565.             }
  566.             know(fragP->fr_next);
  567.             after = fragP->fr_next->fr_address;
  568.             /*
  569.              * Growth may be negative, but variable part of frag cannot
  570.              * have < 0 chars. That is, we can't .org backwards.
  571.              */
  572.             growth = ((target - after ) > 0) ? (target - after) : 0;
  573.  
  574.             growth -= stretch;    /* This is an absolute growth factor */
  575.             break;
  576.  
  577.         case rs_machine_dependent:
  578.             this_state = fragP->fr_subtype;
  579.             this_type = md_relax_table + this_state;
  580.             start_type = this_type;
  581.  
  582.             target = offset;
  583.             if(symbolP){
  584.             know(((symbolP->sy_type & N_TYPE) == N_ABS) ||
  585.                  ((symbolP->sy_type & N_TYPE) == N_SECT));
  586.             know(symbolP->sy_frag);
  587.             know((symbolP->sy_type & N_TYPE) != N_ABS ||
  588.                  symbolP->sy_frag == &zero_address_frag);
  589.  
  590.             target += symbolP->sy_value +
  591.                   symbolP->sy_frag->fr_address;
  592.             /*
  593.              * If frag has yet to be reached on this pass,
  594.              * assume it will move by STRETCH just as we did.
  595.              * If this is not so, it will be because some frag
  596.              * between grows, and that will force another pass.
  597.              */
  598.             if(symbolP->sy_frag->fr_address >= was_address &&
  599.                is_down_range(fragP, symbolP->sy_frag))
  600.                 target += stretch;
  601.             }
  602.             aim = target - address - fragP->fr_fix;
  603.             if(aim < 0){
  604.             /* Look backwards. */
  605.             for(next_state = this_type->rlx_more; next_state; ){
  606.                 if(aim >= this_type->rlx_backward)
  607.                 next_state = 0;
  608.                 else{    /* Grow to next state. */
  609.                 this_state = next_state;
  610.                 this_type = md_relax_table + this_state;
  611.                 next_state = this_type->rlx_more;
  612.                 }
  613.             }
  614.             }
  615.             else{
  616.             /* Look forwards. */
  617.             for(next_state = this_type->rlx_more; next_state; ){
  618.                 if(aim <= this_type->rlx_forward)
  619.                 next_state = 0;
  620.                 else{    /* Grow to next state. */
  621.                 this_state = next_state;
  622.                 this_type = md_relax_table + this_state;
  623.                 next_state = this_type->rlx_more;
  624.                 }
  625.             }
  626.             }
  627.             if((growth = this_type->rlx_length -start_type->rlx_length))
  628.               fragP->fr_subtype = this_state;
  629.             break;
  630.  
  631.           default:
  632.               BAD_CASE(fragP->fr_type);
  633.               break;
  634.         }
  635.         if(growth) {
  636.             stretch += growth;
  637.             stretched++;
  638.         }
  639.         }            /* For each frag in the segment. */
  640.     }while(stretched);    /* Until nothing further to relax. */
  641.  
  642.     /*
  643.      * We now have valid fr_address'es for each frag.  All fr_address's
  644.      * are correct, relative to their own section.  We have made all the
  645.      * fixS for this section that will be made.
  646.      */
  647. }
  648.  
  649. /*
  650.  * Relax_align. Advance location counter to next address that has 'alignment'
  651.  * lowest order bits all 0s.
  652.  */
  653. static
  654. relax_addressT        /* How many addresses does the .align take? */
  655. relax_align(
  656. relax_addressT address, /* Address now. */
  657. long alignment)        /* Alignment (binary). */
  658. {
  659.     relax_addressT mask;
  660.     relax_addressT new_address;
  661.  
  662.     mask = ~ ( (~0) << alignment );
  663.     new_address = (address + mask) & (~ mask);
  664.     return(new_address - address);
  665. }
  666.  
  667. /*
  668.  * is_down_range() is used in relax_section() to determine it one fragment is
  669.  * after another to know if it will also be moved if the first is moved.
  670.  */
  671. static
  672. int
  673. is_down_range(
  674. struct frag *f1,
  675. struct frag *f2)
  676. {
  677.     while(f1){
  678.         if(f1->fr_next == f2)
  679.         return(1);
  680.         f1 = f1->fr_next;
  681.     }
  682.     return(0);
  683. }
  684.